package com.cmc.cloud.cmclink.doc.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.lock.annotation.Lock4j;
import com.cmc.cloud.cmclink.doc.api.document.rep.BookingRequestConfigRespDto;
import com.cmc.cloud.cmclink.doc.api.document.req.BookingRequestConfigReqDto;
import com.cmc.cloud.cmclink.doc.constants.errorconstant.BookingRequestConfigErrorCodeConstants;
import com.cmc.cloud.cmclink.doc.convert.BookingRequestConfigConvert;
import com.cmc.cloud.cmclink.doc.entity.BookingRequestConfigDO;
import com.cmc.cloud.cmclink.doc.mapper.BookingRequestConfigMapper;
import com.cmc.cloud.cmclink.doc.service.BookingRequestConfigService;
import com.cmc.cloud.cmclink.doc.vo.bookingrequestconfigvo.BookingRequestConfigBaseVO;
import com.cmc.cloud.cmclink.doc.vo.bookingrequestconfigvo.BookingRequestConfigCreateReqVO;
import com.cmc.cloud.cmclink.doc.vo.bookingrequestconfigvo.BookingRequestConfigPageReqVO;
import com.cmc.cloud.cmclink.doc.vo.bookingrequestconfigvo.BookingRequestConfigUpdateReqVO;
import com.cmes.framework.common.exception.util.ServiceExceptionUtil;
import com.cmes.framework.common.pojo.PageResult;
import com.cmes.framework.mybatis.core.query.LambdaQueryWrapperX;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.Collections;
import java.util.List;


/**
 * 装船要求用箱要求订舱要求选项配置 Service 实现类
 *
 * @author 招商轮船-管理员
 */
@Service
@Validated
public class BookingRequestConfigServiceImpl implements BookingRequestConfigService {

    @Resource
    private BookingRequestConfigMapper bookingRequestConfigMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    @Lock4j(name = "bookingRequestConfigUnique", keys = {"#createReqVO.getRequestCode", "#createReqVO.getRequestDescEn"})
    public void createBookingRequestConfig(BookingRequestConfigCreateReqVO createReqVO) {
        // 插入
        validateUnique(createReqVO, null);
        BookingRequestConfigDO bookingRequestConfig = BeanUtil.copyProperties(createReqVO, BookingRequestConfigDO.class);
        bookingRequestConfigMapper.insert(bookingRequestConfig);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @Lock4j(name = "bookingRequestConfigUnique", keys = {"#updateReqVO.getRequestCode", "#updateReqVO.getRequestDescEn"})
    public void updateBookingRequestConfig(BookingRequestConfigUpdateReqVO updateReqVO) {
        // 校验存在
        validateBookingRequestConfigExists(updateReqVO.getId());
        validateUnique(updateReqVO, updateReqVO.getId());
        // 更新
        BookingRequestConfigDO updateObj = BeanUtil.copyProperties(updateReqVO, BookingRequestConfigDO.class);
        bookingRequestConfigMapper.updateById(updateObj);
    }

    private void validateUnique(BookingRequestConfigBaseVO vo, Long id) {
        LambdaQueryWrapperX<BookingRequestConfigDO> queryWrapperX = new LambdaQueryWrapperX<BookingRequestConfigDO>()
                .eqIfPresent(BookingRequestConfigDO::getRequestCode, vo.getRequestCode())
                .eqIfPresent(BookingRequestConfigDO::getRequestDescEn, vo.getRequestDescEn());
        if (id != null) {
            queryWrapperX.ne(BookingRequestConfigDO::getId, id);
        }
        if (bookingRequestConfigMapper.selectCount(queryWrapperX) != 0L) {
            throw ServiceExceptionUtil.exception(BookingRequestConfigErrorCodeConstants.BOOKING_REQUEST_CONFIG_EXISTED);
        }
    }

    @Override
    public void deleteBookingRequestConfig(Long id) {
        // 校验存在
        validateBookingRequestConfigExists(id);
        // 删除
        bookingRequestConfigMapper.deleteById(id);
    }

    private void validateBookingRequestConfigExists(Long id) {
        if (bookingRequestConfigMapper.selectById(id) == null) {
            throw ServiceExceptionUtil.exception(BookingRequestConfigErrorCodeConstants.BOOKING_REQUEST_CONFIG_NOT_EXISTS);
        }
    }

    @Override
    public BookingRequestConfigDO getBookingRequestConfig(Long id) {
        return bookingRequestConfigMapper.selectById(id);
    }

    @Override
    public List<BookingRequestConfigDO> getBookingRequestConfigList(Collection<Long> ids) {
        return bookingRequestConfigMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<BookingRequestConfigDO> getBookingRequestConfigPage(BookingRequestConfigPageReqVO reqVO) {
        LambdaQueryWrapperX<BookingRequestConfigDO> queryWrapperX = new LambdaQueryWrapperX<>();
        queryWrapperX.eqIfPresent(BookingRequestConfigDO::getRequestTypeCode, reqVO.getRequestTypeCode());
        if (StringUtils.isNotEmpty(reqVO.getKeyWord())) {
            queryWrapperX.and(
                    wrapper -> wrapper.like(BookingRequestConfigDO::getRequestDescCn, reqVO.getKeyWord())
                            .or().like(BookingRequestConfigDO::getRequestDescEn, reqVO.getKeyWord()));
        }
        return bookingRequestConfigMapper.selectPage(reqVO, queryWrapperX);
    }

    @Override
    public List<BookingRequestConfigRespDto> queryBookingRequestConfig(BookingRequestConfigReqDto bookingRequestConfigReqDto) {
        LambdaQueryWrapperX<BookingRequestConfigDO> lambdaQueryWrapperX = new LambdaQueryWrapperX<>();
        lambdaQueryWrapperX.eqIfPresent(BookingRequestConfigDO::getRequestTypeCode, bookingRequestConfigReqDto.getRequestTypeCode())
                .eq(BookingRequestConfigDO::getEnable, Boolean.TRUE);
        List<BookingRequestConfigDO> bookingRequestConfigDOList = bookingRequestConfigMapper.selectList(lambdaQueryWrapperX);
        if (CollectionUtils.isEmpty(bookingRequestConfigDOList)) {
            return Collections.emptyList();
        }
        return BookingRequestConfigConvert.INSTANCE.convertDto(bookingRequestConfigDOList);
    }
}
